package com.audaque.springboot.foshanupload.core.util.encode;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;

public class AESUtils {
    public AESUtils() {
    }

    public static byte[] encrypt(String key, byte[] src) throws Exception {
        return aes(1, key, src);
    }

    public static String encrypt(String key, String src) throws Exception {
        byte[] bs = aes(1, key, src.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(bs);
    }

    public static byte[] decrypt(String key, byte[] src) throws Exception {
        return aes(2, key, src);
    }

    public static String decrypt(String key, String src) throws Exception {
        byte[] bs = Base64.getDecoder().decode(src);
        bs = aes(2, key, bs);
        return new String(bs, "UTF-8");
    }

    public static byte[] aes(int mode, String key, byte[] src) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed(key.getBytes("UTF-8"));
        keyGenerator.init(256, random);
        SecretKey secretKey = keyGenerator.generateKey();
        IvParameterSpec ips = new IvParameterSpec(secretKey.getEncoded());
        String algorithm = "AES/GCM/NoPadding";
        Cipher cipher = Cipher.getInstance(algorithm, new BouncyCastleProvider());
        cipher.init(mode, secretKey, ips);
        return cipher.doFinal(src);
    }

    public static void main(String[] args) throws Exception {
        if (args != null && args.length == 3) {
            if (Integer.parseInt(args[0]) == 1) {
                System.out.println("明文：" + args[2]);
                System.out.println("密钥：" + args[1]);
                System.out.println("密文：" + encrypt(args[1], args[2]));
            } else {
                System.out.println("密文：" + args[2]);
                System.out.println("密钥：" + args[1]);
                System.out.println("明文：" + decrypt(args[1], args[2]));
            }

        } else {
            System.out.println("参数错误：参数1表示加密或解密(1是加密，2是解密)，参数2表示密钥，参数3表示明文或密文");
        }
    }
}
